#include "app_buffer.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>

#define TEST_BUFFER_SIZE 1024

void test_buffer_basic_operations()
{
    // 初始化缓冲区
    Buffer *buffer = app_buffer_init(TEST_BUFFER_SIZE);
    assert(buffer != NULL);

    // 测试数据
    const char *test_data = "Hello, buffer!";
    int32_t data_len = (int32_t)(strlen(test_data) + 1);

    // 写入数据
    int32_t ret = app_buffer_write(buffer, (void *)test_data, data_len);
    assert(ret == 0);

    // 读取数据
    char read_buff[TEST_BUFFER_SIZE];
    int32_t read_len = app_buffer_read(buffer, read_buff, TEST_BUFFER_SIZE);
    assert(read_len == data_len);
    assert(strcmp(test_data, read_buff) == 0);

    // 释放缓冲区
    app_buffer_free(buffer);
}

void test_buffer_boundary_conditions()
{
    // 初始化缓冲区
    Buffer *buffer = app_buffer_init(TEST_BUFFER_SIZE);
    assert(buffer != NULL);

    // 测试写入超过缓冲区大小
    char large_data[TEST_BUFFER_SIZE * 2];
    int32_t ret = app_buffer_write(buffer, large_data, sizeof(large_data));
    assert(ret == -1);

    // 测试读取空缓冲区
    char read_buff[TEST_BUFFER_SIZE];
    int32_t read_len = app_buffer_read(buffer, read_buff, sizeof(read_buff));
    assert(read_len == 0);

    // 测试读取缓冲区不足
    const char *test_data = "Test data";
    ret = app_buffer_write(buffer, (void *)test_data, strlen(test_data) + 1);
    assert(ret == 0);

    char small_buff[4];
    read_len = app_buffer_read(buffer, small_buff, sizeof(small_buff));
    assert(read_len == -1);

    // 释放缓冲区
    app_buffer_free(buffer);
}

#define THREAD_COUNT 4
#define ITERATIONS 1000

void *writer_thread(void *arg)
{
    Buffer *buffer = (Buffer *)arg;
    char data[32];

    for (int i = 0; i < ITERATIONS; i++)
    {
        snprintf(data, sizeof(data), "Writer %d: %d", (int)pthread_self(), i);

        // 尝试写入，如果缓冲区满则等待后重试
        int32_t ret;
        do
        {
            ret = app_buffer_write(buffer, data, strlen(data) + 1);
            if (ret == -1)
            {
                sleep(1); // 等待1s后重试
            }
        } while (ret == -1);

        usleep(rand() % 1000);
    }
    return NULL;
}

void *reader_thread(void *arg)
{
    Buffer *buffer = (Buffer *)arg;
    char data[32];

    for (int i = 0; i < ITERATIONS;)
    {
        int32_t len = app_buffer_read(buffer, data, sizeof(data));
        if (len > 0)
        {
            assert(len <= (int32_t)sizeof(data));
            printf("Reader %d: %s\n", (int)pthread_self(), data);
            i++;
        }
        usleep(rand() % 1000);
    }
    return NULL;
}

void test_buffer_thread_safety()
{
    Buffer *buffer = app_buffer_init(TEST_BUFFER_SIZE);
    assert(buffer != NULL);

    pthread_t threads[THREAD_COUNT * 2];

    // 创建写线程
    for (int i = 0; i < THREAD_COUNT; i++)
    {
        pthread_create(&threads[i], NULL, writer_thread, buffer);
    }

    // 创建读线程
    for (int i = THREAD_COUNT; i < THREAD_COUNT * 2; i++)
    {
        pthread_create(&threads[i], NULL, reader_thread, buffer);
    }

    // 等待所有线程完成
    for (int i = 0; i < THREAD_COUNT * 2; i++)
    {
        pthread_join(threads[i], NULL);
    }

    app_buffer_free(buffer);
}

int main()
{
    printf("Running buffer tests...\n");

    test_buffer_basic_operations();
    test_buffer_boundary_conditions();
    test_buffer_thread_safety();

    printf("All tests passed!\n");
    return 0;
}
